/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.ssau.utils;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import ru.ssau.entities.Message;
import ru.ssau.entities.User;
import ru.ssau.entities.Thread;
import ru.ssau.lib.StringIntegerPair;
import ru.ssau.lib.XMLizable;

/**
 *
 * @author Desperus
 */
public class XMLHelper {

    public static Element parseString(String str) throws IOException {
        try {
            SAXBuilder builder = new SAXBuilder();
            Reader in = new StringReader(str);
            Document doc = builder.build(in);
            return doc.getRootElement();
        } catch (Exception ex) {
            throw new IOException("Error parsing xml!");
        }
    }

    public static String outputXML(Element root) {
        StringWriter sw = new StringWriter();
        XMLOutputter xout = new XMLOutputter();
        try {
            xout.output(root, sw);
        } catch (IOException ex) {
        }
        return sw.toString();
    }

    public static void saveXMLToFile(Element root, File f) {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
            out.output(root, bw);
            bw.flush();
            bw.close();
        } catch (IOException ex) {
        }
    }

    /*private Element root;

    public XMLHelper(String rootName) {
    root = new Element(rootName);
    }*/
    public XMLHelper() {
    }

    public void addElement(Element root, String name, String value) {
        Element elem = new Element(name);
        elem.setText(StringUtils.getValidString(value));
        addElement(root, elem);
    }

    public void addElement(Element root, Element element) {
        root.addContent(element);
    }

    public void addElement(Element root, String elemName, boolean value) {
        Element elem = new Element(elemName);
        elem.addContent(Boolean.toString(value));
        addElement(root, elem);
    }

    public void addElement(Element root, String elemName, XMLizable object) {
        if (object == null) {
            return;
        }
        Element appElem = new Element(elemName);
        addElement(appElem, object.toXMLElement());
        addElement(root, appElem);
    }

    public void addElement(Element root, String name, Integer value) {
        String val = String.valueOf(value);
        addElement(root, name, StringUtils.getValidString(val));
    }

    public void addElement(Element root, Attribute attr, Map map) {
        Element appElem = new Element("Map");
        if (attr != null) {
            appElem.setAttribute(attr);
        }
        if (map != null) {
            Set keys = map.keySet();
            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
                Integer key = (Integer) iterator.next();
                XMLizable value = (XMLizable) map.get(key);
                Element elem = new Element("MapElement");
                elem.setAttribute("key", String.valueOf(key));
                addElement(elem, value.toXMLElement());
                addElement(appElem, elem);
            }
        }
        addElement(root, appElem);
    }

    //быдлокод((
    public HashMap loadHashMap(Element data, String objClass) {
        HashMap map = null;
        if (objClass.equals("User")) {
            map = new HashMap<Integer, User>();
        } else if (objClass.equals("Thread")) {
            map = new HashMap<Integer, Thread>();
        } else if (objClass.equals("Message")) {
            map = new HashMap<Integer, Message>();
        }
        List<Element> children = data.getChildren("MapElement");
        for (Iterator iterator = children.iterator(); iterator.hasNext();) {
            Element mapElem = (Element) iterator.next();
            Integer key = Integer.valueOf(mapElem.getAttributeValue("key"));
            Element objectElem = mapElem.getChild(objClass);
            Object obj = null;
            if (objClass.equals("User")) {
                obj = new User();
                ((User) obj).loadFromXMLElement(objectElem);
            } else if (objClass.equals("Thread")) {
                obj = new Thread();
                ((Thread) obj).loadFromXMLElement(objectElem);
            } else if (objClass.equals("Message")) {
                obj = new Message();
                ((Message) obj).loadFromXMLElement(objectElem);
            }
            map.put(key, obj);
        }
        return map;
    }

    public void addElement(Element root, String name, Date date) {
        long l = date.getTime();
        addElement(root, name, StringUtils.getValidString(String.valueOf(l)));
    }

    public void addElement(Element root, String name, Attribute attr,
            XMLizable[] objects) {
        Element appElem = new Element(name);
        if (attr != null) {
            appElem.setAttribute(attr);
        }
        for (int i = 0; i < objects.length; i++) {
            addElement(appElem, objects[i].toXMLElement());
        }
        addElement(root, appElem);
    }

    public StringIntegerPair[] loadStringIntegerPairs(Element data) {
        LinkedList<StringIntegerPair> pairs = new LinkedList<StringIntegerPair>();
        List<Element> pairsElem = data.getChildren("StringIntegerPair");
        for (Iterator iterator = pairsElem.iterator(); iterator.hasNext();) {
            StringIntegerPair pair = new StringIntegerPair();
            Element pairElem = (Element) iterator.next();
            pair.loadFromXMLElement(pairElem);
            pairs.add(pair);
        }
        StringIntegerPair[] pairsArr = new StringIntegerPair[pairs.size()];
        pairs.toArray(pairsArr);
        return pairsArr;
    }

    public void addElement(Element root, String name, XMLizable[] objects) {
        addElement(root, name, null, objects);
    }
}
